home *** CD-ROM | disk | FTP | other *** search
- Subject: v11i056: Mail user's shell, Part06/12
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: island!argv@Sun.COM (Dan Heller)
- Posting-number: Volume 11, Issue 56
- Archive-name: mush5.7/Part06
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 12)."
- # Contents: curses.c msgs.c mush.h
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'curses.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'curses.c'\"
- else
- echo shar: Extracting \"'curses.c'\" \(17549 characters\)
- sed "s/^X//" >'curses.c' <<'END_OF_FILE'
- X/* @(#)curses.c (c) copyright 3/18/87 (Dan Heller) */
- X
- X/* curses.c -- routine to deal with the curses interface */
- X#ifdef CURSES
- X
- X#include "mush.h"
- X#include "bindings.h"
- X
- Xcurses_init(argc, argv)
- Xregister char **argv;
- X{
- X char buf[80];
- X extern char *UP, ttytype[];
- X
- X if (argv && *++argv && !strcmp(*argv, "-?"))
- X return help(0, "curses", cmd_help);
- X if (iscurses) {
- X print("You can't run curses from the curses mode (silly).");
- X return -1;
- X }
- X if (ison(glob_flags, IS_GETTING)) {
- X print("Finish your letter first.\n");
- X return -1;
- X }
- X#ifdef SUNTOOL
- X if (istool) {
- X print("My, aren't we the adventuresome type!");
- X timerclear(&(mail_timer.it_interval));
- X timerclear(&(mail_timer.it_value));
- X tool_destroy(tool), istool = FALSE;
- X curses_init(0, 0);
- X do_loop(); /* doesn't return */
- X }
- X#endif SUNTOOL
- X
- X /* you can not start curses in no echo mode.. must be in normal mode */
- X echo(), nocrmode();
- X (void) initscr();
- X#ifdef SIGCONT
- X /* initscr will play with signals -- make sure they're set right. */
- X (void) signal(SIGTSTP, stop_start);
- X (void) signal(SIGCONT, stop_start);
- X#endif SIGCONT
- X if (!UP || !*UP) {
- X print("Terminal type %s can not use the curses interface.\n", ttytype);
- X return -1;
- X }
- X iscurses = TRUE;
- X noecho(), crmode(); /* reset tty state -- do not use "echo_on/off()" */
- X scrollok(stdscr, TRUE);
- X /* if the user hasn't set his screen explicitely, set it for him */
- X if (!do_set(set_options, "screen"))
- X switch (_tty.sg_ospeed) {
- X case B300 : screen = min(LINES-2, 7);
- X when B1200 : screen = min(LINES-2, 14);
- X when B2400 : screen = min(LINES-2, 22);
- X otherwise : screen = LINES-2;
- X }
- X else
- X screen = min(screen, LINES-2);
- X crt = LINES;
- X if (argc)
- X (void) cmd_line(sprintf(buf, "headers %d", current_msg+1), msg_list);
- X if (!do_set(set_options, "no_reverse"))
- X turnon(glob_flags, REV_VIDEO);
- X turnoff(glob_flags, CONT_PRNT);
- X return -1; /* doesn't affect messages */
- X}
- X
- X/*
- X * get input in cbreak mode and execute the appropriate command.
- X * when the command is done (usually), the user is prompted to
- X * hit any key to continue. At this point, the user may enter a
- X * new command so no screen refreshing needds to be done. This
- X * new command is returned to caller and may be passed back.
- X *
- X * The variable "cntd_cmd" (continued command) is set to true if
- X * this routine is called with the passed parameter (c) > 0. If
- X * so, then the character passed is the character input by the
- X * user at the last "hit return" prompt indicating that he wants
- X * to execute a new command and not draw the screen.
- X *
- X * cntd_cmd is also set to true if the command that the user invokes
- X * causes any sort of output that requires a screen refresh. The
- X * variable redo is set to 1 if the header page not only requires
- X * redrawing, but updating ... (new call to do_hdrs)
- X *
- X * calls that say: print("%s", compose_hdr(current_msg)) are constructed
- X * that way cuz if the header has a `%' in it, then print will try to
- X * expand it.
- X */
- Xcurses_command(c)
- Xregister int c;
- X{
- X char buf[BUFSIZ], file[128], list[128];
- X int n, cntd_cmd = (c > 0), curlin;
- X static int redo; /* set if headers should be redrawn */
- X
- X clear_msg_list(msg_list); /* play it safe */
- X if (!cntd_cmd) {
- X (void) check_new_mail();
- X curlin = max(1, current_msg - n_array[0] + 1);
- X (void) strncpy(buf, stdscr->_y[curlin], COLS-1);
- X buf[COLS-1] = 0; /* strncpy does not null terminate */
- X if (ison(glob_flags, REV_VIDEO) && msg_cnt)
- X STANDOUT(curlin, 0, buf);
- X mail_status(0);
- X move(curlin, 0), refresh();
- X /* reprint to remove reverse video from current line (don't refresh) */
- X if (ison(glob_flags, REV_VIDEO))
- X mvaddstr(curlin, 0, buf);
- X c = getcmd(); /* get input AFTER line redrawn without reverse video */
- X }
- X buf[0] = list[0] = file[0] = '\0';
- X
- X /* goto a specific line number */
- X if (c == C_GOTO_MSG) {
- X c = C_NULL;
- X if (msg_cnt <= 1)
- X print("Not enough messages.");
- X else if (curses_msg_list(strcpy(buf, "goto msg: "), list, msg_list)) {
- X for (n = 0; !msg_bit(msg_list, n); n++)
- X ;
- X if ((current_msg = n) < n_array[0] || n > n_array[screen-1])
- X redo = 1;
- X }
- X if (cntd_cmd && msg_cnt)
- X print("%s", compose_hdr(current_msg));
- X if (cntd_cmd)
- X putchar('\n');
- X } else if (c == C_WRITE_LIST || c == C_SAVE_LIST || c == C_COPY_LIST
- X || c == C_DELETE_LIST || c == C_UNDEL_LIST) {
- X
- X if (msg_cnt <= 1)
- X print("Not enough messages."), c = C_NULL;
- X else if (!curses_msg_list(sprintf(buf, "%s msg list: ",
- X (c == C_WRITE_LIST)? "write" : (c == C_SAVE_LIST)? "save" :
- X (c == C_DELETE_LIST)? "delete" : "undelete"), list, msg_list))
- X c = C_NULL;
- X if (cntd_cmd)
- X putchar('\n');
- X }
- X
- X /* first do non-mail command stype stuff */
- X switch (c) {
- X case C_NULL : ;
- X
- X /* screen optimization stuff */
- X when C_REVERSE :
- X if (ison(glob_flags, REV_VIDEO))
- X turnoff(glob_flags, REV_VIDEO);
- X else
- X turnon(glob_flags, REV_VIDEO);
- X
- X when C_REDRAW : if (!redo) redraw();
- X
- X /*
- X * screen movement
- X */
- X when C_NEXT_MSG :
- X /* case 'j' : case 'J' : case '+' : case '\n' : /* next */
- X if (current_msg + 2 > msg_cnt || !cntd_cmd && curlin == screen)
- X bell(); /* reached the end */
- X else {
- X if (++current_msg > n_array[screen-1])
- X redo = 1;
- X if (cntd_cmd)
- X print("%s", compose_hdr(current_msg)), putchar('\n');
- X }
- X when C_PREV_MSG :
- X /* when 'k' : case 'K' : case '-' : case CTRL(k) : /* previous */
- X if (!cntd_cmd && curlin == 1 || current_msg == 0)
- X bell(); /* at the beginning */
- X else {
- X if (--current_msg < n_array[0])
- X redo = 1;
- X if (cntd_cmd)
- X print("%s", compose_hdr(current_msg)), putchar('\n');
- X }
- X when C_FIRST_MSG : case C_LAST_MSG :
- X n = current_msg;
- X if (c == C_FIRST_MSG && (current_msg = 0) < n_array[0] ||
- X c == C_LAST_MSG && (current_msg = msg_cnt-1)> n_array[screen-1])
- X if (!cntd_cmd)
- X (void) cmd_line(sprintf(buf, "headers %d", current_msg+1),
- X msg_list);
- X else
- X redo = 1;
- X if (cntd_cmd && n != current_msg)
- X print("%s", compose_hdr(current_msg)), putchar('\n');
- X /* top and bottom of headers screen */
- X when C_TOP_PAGE : case C_BOTTOM_PAGE :
- X if (!cntd_cmd)
- X if (c == C_TOP_PAGE)
- X current_msg = n_array[0];
- X else
- X current_msg = min(n_array[screen-1], msg_cnt-1);
- X else
- X bell();
- X when C_NEXT_SCREEN : /* next page */
- X if (msg_cnt > screen) {
- X (void) cmd_line(strcpy(buf, "headers +"), msg_list);
- X current_msg = n_array[0];
- X return redo = 0;
- X } else
- X bell();
- X when C_PREV_SCREEN : /* previous page */
- X if (current_msg > 0 || cntd_cmd)
- X (void) cmd_line(strcpy(buf, "headers -"), msg_list), redo = 0;
- X current_msg = (msg_cnt <= 1)? 0 : n_array[0];
- X return 0;
- X /* break; (not stated for lint) */
- X
- X case C_SHOW_HDR :
- X if (cntd_cmd && msg_cnt)
- X puts(compose_hdr(current_msg));
- X
- X /* read from/save to record file (.mushrc) */
- X when C_SOURCE : case C_SAVEOPTS :
- X print("%s filename [default]: ",
- X (c == C_SOURCE)? "source" : "save options to");
- X if (Getstr(file, LINES-40, 0) < 0) {
- X clr_bot_line();
- X return 0;
- X }
- X iscurses = FALSE;
- X turnon(glob_flags, PRE_CURSES);
- X (void) cmd_line(sprintf(buf, "%s %s",
- X (c == C_SOURCE) ? "source" : "saveopts", file), msg_list);
- X iscurses = TRUE;
- X turnoff(glob_flags, PRE_CURSES);
- X cntd_cmd = 1;
- X
- X /*
- X * search commands
- X */
- X when C_NEXT_SEARCH : case C_PREV_SEARCH : case C_CONT_SEARCH :
- X if (c != C_CONT_SEARCH)
- X c = search(0 + (c == C_PREV_SEARCH));
- X else
- X c = search(-1);
- X if (cntd_cmd)
- X putchar('\n');
- X if (c == 0)
- X break;
- X if (cntd_cmd)
- X print("%s", compose_hdr(current_msg)), putchar('\n');
- X if (n_array[0] > current_msg || n_array[screen-1] < current_msg) {
- X redo = 1;
- X if (!cntd_cmd)
- X (void) cmd_line(sprintf(buf, "headers %d",
- X current_msg+1), msg_list);
- X }
- X
- X /*
- X * actions on messages
- X */
- X /* delete/undelete */
- X when C_DELETE_MSG : case C_DELETE_LIST :
- X case C_UNDEL_MSG : case C_UNDEL_LIST :
- X if (!msg_cnt) {
- X print("No messages.");
- X if (cntd_cmd)
- X putchar('\n');
- X break;
- X }
- X if (!*list)
- X set_msg_bit(msg_list, current_msg);
- X turnon(glob_flags, DO_UPDATE);
- X for (n = 0; n < msg_cnt; n++)
- X if (msg_bit(msg_list, n)) {
- X if (c == C_DELETE_MSG || c == C_DELETE_LIST)
- X turnon(msg[n].m_flags, DELETE);
- X else
- X turnoff(msg[n].m_flags, DELETE);
- X if (!cntd_cmd && msg_cnt < screen ||
- X !cntd_cmd && n >= n_array[0] && n <= n_array[screen-1])
- X mvaddstr(max(1, n - n_array[0] + 1), 0, compose_hdr(n));
- X else
- X redo = 1;
- X }
- X if (cntd_cmd || *list) {
- X if (cntd_cmd) { /* print(), THEN putchar() -- overwrite line */
- X print("%sdeleted %s",
- X (c == C_DELETE_MSG || c == C_DELETE_LIST)? "":"un", list);
- X putchar('\n');
- X }
- X if (ison(msg[current_msg].m_flags, DELETE))
- X (void) next_msg(FALSE, DELETE);
- X if (do_set(set_options, "autoprint"))
- X return C_DISPLAY_MSG;
- X if (cntd_cmd)
- X puts(compose_hdr(current_msg));
- X }
- X
- X /*
- X * write/save messages. If a list is necessary, the user already
- X * entered it above since he must have used a capital letter. If so,
- X * list will contain good data (already been validated above).
- X * if a list is given, set iscurses to 0 so that print statements
- X * will scroll and the user sees the multiple output. else, one
- X * line can go on the bottom line just fine.
- X */
- X when C_WRITE_MSG : case C_SAVE_MSG : case C_COPY_MSG :
- X case C_WRITE_LIST : case C_SAVE_LIST : case C_COPY_LIST : {
- X register char *p =
- X (c == C_WRITE_MSG || c == C_WRITE_LIST)? "write" :
- X (c == C_SAVE_MSG || c == C_SAVE_LIST)? "save" : "copy";
- X print(sprintf(buf, "filename to %s [mbox]: ", p));
- X if (Getstr(file, COLS-1-strlen(buf), 0) >= 0) {
- X char *argv[3];
- X clr_bot_line();
- X argv[0] = strcpy(buf, p);
- X argv[1] = file;
- X argv[2] = NULL;
- X if (!*list)
- X set_msg_bit(msg_list, current_msg);
- X move(LINES-1, 0), refresh();
- X if (*list)
- X iscurses = FALSE;
- X turnon(glob_flags, IS_PIPE);
- X if (save_msg(2, argv, msg_list) < 0)
- X *list = 0;
- X turnoff(glob_flags, IS_PIPE);
- X if (cntd_cmd)
- X putchar('\n'), puts(compose_hdr(current_msg));
- X if (*list)
- X iscurses = cntd_cmd = redo = TRUE;
- X else if (!cntd_cmd && msg_cnt)
- X mvaddstr(curlin, 0, compose_hdr(current_msg));
- X } else {
- X print("No messages saved.");
- X if (cntd_cmd)
- X putchar('\n');
- X }
- X }
- X
- X /* preserve message */
- X when C_PRESERVE :
- X if (!msg_cnt) {
- X print("No messages.");
- X if (cntd_cmd)
- X putchar('\n');
- X break;
- X }
- X if (ison(msg[current_msg].m_flags, PRESERVE))
- X turnoff(msg[current_msg].m_flags, PRESERVE);
- X else
- X turnon(msg[current_msg].m_flags, PRESERVE);
- X if (cntd_cmd) {
- X print("%s", compose_hdr(current_msg)), putchar('\n');
- X redo = 1;
- X } else
- X mvaddstr(curlin, 0, compose_hdr(current_msg));
- X
- X /* order messages (sort) and rediesplay the headers */
- X when C_SORT : case C_REV_SORT :
- X (void) strcpy(file, "sort");
- X if (c == C_REV_SORT) {
- X print("Reverse "), turnon(glob_flags, CONT_PRNT);
- X (void) strcat(file, " -");
- X }
- X print("Order messages by [Status, date, subject, author]: ");
- X if ((c = getchar()) == 's' || c == 'S' || c == 'd' || c == 'a') {
- X print("reordering messages...");
- X (void) cmd_line(sprintf(buf, "%s %c", file, c), msg_list);
- X print_more("done.");
- X if (cntd_cmd)
- X putchar('\n'), puts(compose_hdr(current_msg));
- X redo = 1;
- X } else
- X clr_bot_line();
- X
- X when C_QUIT_HARD :
- X (void) quit(0, DUBL_NULL);
- X redo = 1; /* new mail must have come in */
- X
- X /* quit or update -- vrfy_update (returns 1 if updated) */
- X when C_QUIT : case C_UPDATE :
- X if (!vrfy_update(&cntd_cmd, &redo))
- X if (c == C_UPDATE)
- X break;
- X else
- X turnoff(glob_flags, DO_UPDATE);
- X if (c == C_QUIT) {
- X putchar('\n');
- X cleanup(0);
- X redo = 1;
- X }
- X
- X when C_EXIT : case C_EXIT_HARD :
- X clr_bot_line();
- X iscurses = FALSE;
- X if (c != C_EXIT && c != C_EXIT_HARD)
- X putchar('\n');
- X cleanup(0);
- X
- X /* change to a new folder */
- X when C_FOLDER :
- X for (;;) {
- X print("New folder (?=list): ");
- X if (Getstr(file, COLS-22, 0) > 0) {
- X if (!strcmp(file, "?")) {
- X clr_bot_line();
- X iscurses = 0;
- X puts("folders in your folder directory:");
- X (void) cmd_line(strcpy(buf, "folders"), msg_list);
- X puts("Precede folder names with a +. `%' to specify system mailbox.");
- X cntd_cmd = iscurses = 1;
- X continue;
- X }
- X clearok(stdscr, FALSE);
- X if (strcmp(file, "-?"))
- X vrfy_update(&cntd_cmd, &redo);
- X move(LINES-1, 0), refresh();
- X if (cmd_line(sprintf(buf, "folder ! -N %s", file),
- X msg_list) == -1) {
- X /* error message was printed; leave room to read it */
- X putchar('\n');
- X cntd_cmd = 1, redo = 0;
- X } else
- X redo = 1, cntd_cmd = 0;
- X break;
- X } else {
- X print("\"%s\" unchanged.", mailfile);
- X if (cntd_cmd)
- X putchar('\n');
- X break;
- X }
- X }
- X
- X /* shell escape */
- X when C_SHELL_ESC :
- X print("Shell command: ");
- X if (Getstr(file, COLS-24, 0) < 0)
- X clr_bot_line();
- X else {
- X putchar('\n');
- X iscurses = FALSE;
- X (void) cmd_line(sprintf(buf, "sh %s", file), msg_list);
- X iscurses = TRUE;
- X cntd_cmd = 1;
- X }
- X
- X /* do a line-mode like command */
- X when C_CURSES_ESC :
- X print(":");
- X if (Getstr(buf, COLS-2, 0) < 0)
- X break;
- X putchar('\n');
- X iscurses = FALSE;
- X if (!*buf) {
- X /* return -1 because iscurses = 0 is not enough! */
- X redo = 0;
- X endwin(); /* this turns echoing back on! */
- X echo_off();
- X return -1;
- X }
- X (void) cmd_line(buf, msg_list);
- X /* they may have affected message status or had text output */
- X cntd_cmd = redo = 1;
- X iscurses = TRUE;
- X if (msg_cnt)
- X puts(compose_hdr(current_msg));
- X
- X /* send message to printer */
- X when C_PRINT_MSG : lpr(0, DUBL_NULL, msg_list);
- X
- X /* cd */
- X when C_CHDIR :
- X print("chdir to [.]: ");
- X if (Getstr(file, COLS-12, 0) < 0)
- X break;
- X clr_bot_line();
- X (void) cmd_line(sprintf(buf, "cd %s", file), msg_list);
- X if (cntd_cmd)
- X putchar('\n');
- X
- X /* variable settings */
- X when C_VAR_SET : case C_IGNORE : case C_ALIAS : case C_OWN_HDR :
- X curs_vars(c, &cntd_cmd); /* cntd_cmd is reset if there's output! */
- X
- X when C_VERSION :
- X do_version(); /* duh */
- X if (cntd_cmd)
- X putchar('\n');
- X
- X when C_MAIL_FLAGS :
- X print("flags [-?]: ");
- X if ((c = Getstr(file, COLS-50, 0)) < 0)
- X break;
- X putchar('\n');
- X if (c == 0)
- X (void) strcpy(file, "-?");
- X /* Fall thru */
- X case C_MAIL :
- X clr_bot_line();
- X iscurses = FALSE;
- X (void) cmd_line(sprintf(buf, "mail %s", file), msg_list);
- X iscurses = TRUE, cntd_cmd = 1;
- X if (msg_cnt)
- X print("%s", compose_hdr(current_msg)), putchar('\n');
- X
- X /* reply to mail */
- X when C_REPLY_SENDER : case C_REPLY_ALL : {
- X register char *p = (c == C_REPLY_ALL)? "replyall" : "replysender";
- X clr_bot_line();
- X iscurses = FALSE;
- X (void) cmd_line(sprintf(buf, "%s %d", p, current_msg+1),
- X msg_list);
- X iscurses = TRUE, cntd_cmd = 1;
- X if (msg_cnt)
- X print("%s", compose_hdr(current_msg)), putchar('\n');
- X }
- X
- X /* type out a message */
- X when C_DISPLAY_MSG : case C_TOP_MSG : case C_DISPLAY_NEXT :
- X if (!msg_cnt ||
- X c != C_DISPLAY_NEXT && ison(msg[current_msg].m_flags, DELETE)) {
- X if (!msg_cnt)
- X print("No messages.");
- X else
- X print("Message %d deleted; type 'u' to undelete.",
- X current_msg+1);
- X if (cntd_cmd)
- X putchar('\n');
- X break;
- X }
- X clr_bot_line();
- X iscurses = FALSE;
- X if (cntd_cmd)
- X putchar('\n');
- X if (c == C_DISPLAY_MSG)
- X c = cmd_line(strcpy(buf, "type"), msg_list);
- X else if (c == C_TOP_MSG)
- X c = cmd_line(strcpy(buf, "top"), msg_list);
- X else
- X c = cmd_line(strcpy(buf, "next"), msg_list);
- X if (c > -1)
- X cntd_cmd = redo = 1;
- X iscurses = TRUE;
- X puts(compose_hdr(current_msg));
- X
- X /* bind a key or string to a command */
- X when C_BIND : case C_UNBIND : {
- X char *argv[2];
- X argv[0] = (c == C_BIND) ? "bind" : "unbind";
- X argv[1] = NULL;
- X if (bind_it(0, argv) < -1)
- X cntd_cmd = 1;
- X else if (cntd_cmd) /* if it was already set anyway */
- X putchar('\n');
- X }
- X
- X /* help stuff */
- X when C_HELP :
- X (void) c_bind(NULL);
- X cntd_cmd = 1;
- X if (msg_cnt)
- X puts(compose_hdr(current_msg));
- X
- X /* now do interactive stuff as if run from the mush shell */
- X otherwise :
- X bell();
- X if (cntd_cmd) {
- X /* use print instead of puts to overwrite hit_return msg */
- X print("unknown command"), putchar('\n');
- X redo = 1;
- X }
- X }
- X
- X if (cntd_cmd) {
- X int old_cnt = msg_cnt;
- X if (!(c = hit_return()) && !redo && msg_cnt == old_cnt)
- X redraw();
- X clr_bot_line();
- X if (old_cnt != msg_cnt)
- X redo = 1;
- X if (c)
- X return c;
- X }
- X if (redo) {
- X n = current_msg;
- X clear();
- X if (msg_cnt < screen || n_array[0] < n && n < n_array[screen-1])
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X else
- X (void) cmd_line(sprintf(buf, "headers %d", n+1), msg_list);
- X redo = 0;
- X }
- X return 0;
- X}
- X
- Xvrfy_update(cntd_cmd, redo)
- Xint *cntd_cmd, *redo;
- X{
- X char buf[16];
- X int c;
- X
- X /* update current folder */
- X if (ison(glob_flags, DO_UPDATE)) {
- X print("Update %s [y]? ", mailfile);
- X if ((c = getchar()) == 'n' || c == 'N' || c == 7 || c == 127 || c == 4){
- X print("%s unmodified.", mailfile);
- X if (*cntd_cmd)
- X putchar('\n');
- X return 0;
- X }
- X (void) cmd_line(strcpy(buf, "update"), msg_list);
- X if (*cntd_cmd)
- X *redo = 1, *cntd_cmd = 0;
- X }
- X turnoff(glob_flags, DO_UPDATE);
- X return 1; /* make sure bottom line is clear and no reverse video */
- X}
- X#endif CURSES
- END_OF_FILE
- if test 17549 -ne `wc -c <'curses.c'`; then
- echo shar: \"'curses.c'\" unpacked with wrong size!
- fi
- # end of 'curses.c'
- fi
- if test -f 'msgs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'msgs.c'\"
- else
- echo shar: Extracting \"'msgs.c'\" \(16268 characters\)
- sed "s/^X//" >'msgs.c' <<'END_OF_FILE'
- X/* @(#)msgs.c (c) copyright 10/18/86 (Dan Heller) */
- X
- X#include "mush.h"
- X#ifdef SYSV
- X#include <sys/locking.h>
- X#endif SYSV
- X
- Xvoid
- Xdisplay_msg(n, flg)
- Xregister int n;
- Xlong flg;
- X{
- X register FILE *pp;
- X
- X if (ison(msg[n].m_flags, DELETE)) {
- X print("Message %d deleted; ", n+1);
- X if (istool)
- X print_more("Select UNDELETE to read.");
- X else if (iscurses)
- X print_more("Type 'u' to undelete.");
- X else
- X print("Type 'undelete %d' to undelete\n", n+1);
- X return;
- X }
- X set_isread(n);
- X if (ison(flg, TOP)) {
- X turnon(flg, NO_HEADER);
- X print("Top of "), turnon(glob_flags, CONT_PRNT);
- X }
- X
- X if (!istool && isoff(flg, NO_PAGE) &&
- X crt < msg[n].m_lines && isoff(flg, TOP)) {
- X turnon(glob_flags, IGN_SIGS);
- X echo_on();
- X if (!(pp = popen(pager, "w")))
- X error(pager);
- X else {
- X fprintf(pp, "Message #%d (%d lines)\n", n+1, msg[n].m_lines);
- X (void) copy_msg(n, pp, flg);
- X (void) pclose(pp);
- X }
- X echo_off();
- X turnoff(glob_flags, IGN_SIGS);
- X } else {
- X print("Message #%d (%d lines)\n", n+1, msg[n].m_lines);
- X (void) copy_msg(n, stdout, flg);
- X }
- X}
- X
- X/*
- X * copy message 'n' to file "fp" according to various flag arguments
- X * return number of lines copied or -1 if system error on fputs.
- X */
- Xcopy_msg(n, fp, flags)
- Xregister int n;
- Xlong flags;
- Xregister FILE *fp;
- X{
- X register int ignoring = 0, lines = 0;
- X register char *indent_str;
- X int on_hdr = 1, top, squeeze = FALSE;
- X char line[BUFSIZ];
- X
- X still_more = 0;
- X if (ison(flags, TOP)) {
- X register char *p = do_set(set_options, "toplines");
- X top = (p)? atoi(p) : crt;
- X }
- X if (do_set(set_options, "alwaysignore"))
- X turnoff(flags, NO_IGNORE);
- X if (isoff(flags, NO_IGNORE) && do_set(set_options, "squeeze"))
- X squeeze = TRUE;
- X
- X#ifdef SUNTOOL
- X if (istool && fp == stdout) {
- X register int x = (msg[n].m_lines + 2) * l_height(curfont);
- X if (x > 32765) { /* to overcome a bug in pixrects that sun won't fix */
- X print("message too big to display using this font");
- X return 0;
- X }
- X if (x < msg_rect.r_height) /* make it at least as big as the window */
- X x = msg_rect.r_height;
- X do_clear();
- X lock_cursors();
- X if (!(msg_pix = mem_create(msg_rect.r_width, x, 1))) {
- X error("mem_create");
- X return 0;
- X }
- X pr_rop(msg_pix, 0,0, msg_rect.r_width-1, x-1, PIX_CLR, 0,0,0);
- X on_hdr = 1;
- X }
- X#endif SUNTOOL
- X if (ison(flags, INDENT) &&
- X (!(indent_str = do_set(set_options, "indent_str")) ||
- X !strcmp(indent_str, "indent_str")))
- X indent_str = DEF_INDENT_STR;
- X (void) fseek(tmpf, msg[n].m_offset, L_SET);
- X while (still_more < msg[n].m_size && fgets(line, BUFSIZ, tmpf)) {
- X still_more += strlen(line);
- X
- X /*
- X * If squeeze is one, all blanks lines squeeze down to one blank line.
- X * If squeeze is two, squeezing is in progress. Otherwise, wait for \n.
- X */
- X if (*line == '\n') {
- X if (on_hdr) /* blank line -- end of header */
- X turnoff(flags, NO_HEADER), on_hdr = 0;
- X if (squeeze > 1)
- X continue;
- X else if (squeeze)
- X squeeze = 2;
- X } else if (squeeze > 1)
- X squeeze = 1;
- X
- X if (ison(flags, UPDATE_STATUS))
- X if (!strncmp(line, "Status:", 7))
- X continue; /* ignore this and other "Status" lines */
- X else if (!on_hdr) {
- X /* preserve NEW/UNREAD status on preserved messages */
- X if (isoff(msg[n].m_flags, PRESERVE)) {
- X (void) strcpy(line, "Status: O");
- X if (isoff(msg[n].m_flags, UNREAD))
- X (void) strcat(line, "R");
- X (void) strcat(line, "\n");
- X fputs(line, fp);
- X (void) strcpy(line, "\n");
- X }
- X turnoff(flags, UPDATE_STATUS);
- X }
- X if (on_hdr && isoff(flags, NO_IGNORE)) {
- X register char *p = any(line, " \t:");
- X if (!p)
- X ignoring = 0, on_hdr = 0;
- X else if (ignoring)
- X if (*p != ':') {
- X Debug("Ignoring: %s", line);
- X continue;
- X }
- X else
- X ignoring = 0;
- X if (p && *p == ':') {
- X register struct options *opts;
- X *p = 0;
- X ignoring = 0;
- X for (opts = ignore_hdr; opts; opts = opts->next)
- X if (!lcase_strcmp(opts->option, line)) {
- X ignoring = 1;
- X break;
- X }
- X *p = ':';
- X if (ignoring) {
- X Debug("Ignoring: %s", line);
- X continue;
- X }
- X }
- X }
- X if (!on_hdr && ison(flags, TOP) && !--top)
- X break;
- X if (isoff(flags, NO_HEADER)) {
- X /* note that function returns the number of lines */
- X lines++;
- X#ifdef SUNTOOL
- X if (istool && fp == stdout) {
- X Addstr(line);
- X continue;
- X }
- X#endif SUNTOOL
- X if (ison(flags, INDENT))
- X fputs(indent_str, fp);
- X (void) fputs(line, fp);
- X if (errno == ENOSPC)
- X return -1;
- X }
- X }
- X#ifdef SUNTOOL
- X if (istool && fp == stdout) {
- X unlock_cursors();
- X txt.y = still_more = msg_rect.r_height;
- X scroll_win(0); /* causes a display */
- X }
- X#endif SUNTOOL
- X return lines;
- X}
- X
- X/* get mail from whatever the mailfile points to. open a tempfile for
- X * appending, then close it and reopen it for read-only. some systems
- X * have flakey read/write access.
- X */
- Xvoid
- Xgetmail()
- X{
- X register FILE *mail_fp;
- X int lines = 0, get_status = 1;
- X long ftell(), bytes;
- X char line[BUFSIZ];
- X
- X if (!(mail_fp = fopen(mailfile, "r"))) {
- X error("Cannot open %s", mailfile);
- X return;
- X }
- X /*
- X * since this file is usually open for read-only, close it and then
- X * reopen it for appending. This is done to compensate for errors
- X * in XENIX and to play it safe with non-essentially writable files.
- X * see more notes below (end of proc).
- X */
- X (void) fclose(tmpf);
- X {
- X int omask = umask(077);
- X tmpf = fopen(tempfile, "a");
- X (void) umask(omask);
- X if (!tmpf) {
- X error("can't open %s for appending", tempfile);
- X (void) fclose(mail_fp);
- X return;
- X }
- X }
- X#ifdef SYSV
- X (void) locking(fileno(mail_fp), LK_LOCK, 0);
- X#else
- X#ifdef BSD
- X if (flock(fileno(mail_fp), LOCK_SH)) /* if file is locked, flock waits */
- X error("WARNING: could not lock %s", mailfile);
- X#endif BSD
- X#endif SYSV
- X
- X (void) fseek(mail_fp, ftell(tmpf), 0);
- X
- X while (fgets(line, BUFSIZ, mail_fp) != NULL) {
- X if (!strncmp(line, "From ", 5)) {
- X if (msg_cnt == MAXMSGS-1) {
- X print("WARNING: exceeded %d messages.\n", MAXMSGS);
- X print("You should split \"%s\" into smaller files.\n",mailfile);
- X /* make sure that tempfile isn't removed!! */
- X turnon(glob_flags, IGN_SIGS);
- X cleanup(0); /* probably a more elegant way to exit, but... */
- X }
- X bytes = ftell(tmpf);
- X /* finish up message structure from previous message.
- X * if this is incorporating new mail, check "lines" to
- X * see if previous message has already been set!
- X */
- X if (msg_cnt && lines) {
- X msg[msg_cnt-1].m_size = bytes - msg[msg_cnt-1].m_offset;
- X msg[msg_cnt-1].m_lines = lines;
- X }
- X msg[msg_cnt].m_offset = bytes;
- X msg[msg_cnt].m_flags = lines = 0;
- X turnon(msg[msg_cnt].m_flags, UNREAD); /* initialize */
- X
- X fputs(line, tmpf);
- X if (errno == ENOSPC)
- X fs_error();
- X
- X /* we've read the "From " line, now read the rest of
- X * the message headers till we get to a blank line.
- X */
- X while (fgets(line, BUFSIZ, mail_fp) && (*line != '\n')) {
- X register char *p = line;
- X if (get_status && !(get_status = strncmp(p, "Status:", 7))) {
- X turnon(msg[msg_cnt].m_flags, OLD);
- X for (p += 8 ; *p != '\n'; p++)
- X switch(*p) {
- X case 'R': turnoff(msg[msg_cnt].m_flags, UNREAD);
- X }
- X }
- X fputs(line, tmpf), lines++;
- X if (errno == ENOSPC)
- X fs_error();
- X }
- X msg_cnt++, get_status = 1;
- X }
- X fputs(line, tmpf), lines++;
- X if (errno == ENOSPC)
- X fs_error();
- X }
- X /* msg_cnt may be 0 if there is an error with the format of mailfile */
- X if (msg_cnt) {
- X msg[msg_cnt-1].m_size = ftell(tmpf) - msg[msg_cnt-1].m_offset;
- X msg[msg_cnt-1].m_lines = lines;
- X }
- X#ifdef SYSV
- X locking(fileno(mail_fp), LK_UNLCK, 0);
- X#endif /* SYSV */
- X fclose(mail_fp); /* implicit unlock */
- X /* I've had problems with sys-v opening a file for read/write. I'd
- X * try fgets after a seek to an arbitrary place and get NULL. "w+"
- X * could be broken (XENIX), so play it safe anyway.
- X */
- X fclose(tmpf);
- X if (!(tmpf = fopen(tempfile, "r")))
- X error("can't open %s for reading", tempfile);
- X}
- X
- Xfs_error()
- X{
- X error("WARNING: can't write to \"%s\"", tempfile);
- X print("Read the manual on what to do on full file systems.\n");
- X cleanup(0);
- X}
- X
- X/*
- X * copy temp or whatever back to mailfile
- X * Return 0 if new mail came and user doesn't want to exit.
- X */
- Xcopyback()
- X{
- X register int new = 0, i, j=0, k=0;
- X register long flg = 0;
- X register FILE *mbox = NULL_FILE, *mail_fp;
- X char *mbox_file, action = 0;
- X int hold = 0, delete_it = 0, dont_unlink = FALSE;
- X
- X#ifdef SUNTOOL
- X if (istool) {
- X timerclear(&(mail_timer.it_interval));
- X timerclear(&(mail_timer.it_value));
- X }
- X#endif SUNTOOL
- X if (ison(glob_flags, READ_ONLY)) {
- X print("Can't update %s: read only\n", mailfile);
- X return 1;
- X }
- X if (check_new_mail()) {
- X new = 1;
- X if (!istool) {
- X char buf[256];
- X if (iscurses)
- X putchar('\n');
- X print("Really quit? "), fflush(stdout);
- X buf[0] = 0;
- X if (!Getstr(buf, 256, 0) || lower(*buf) != 'y')
- X return 0;
- X }
- X } else if (!msg_cnt) /* prevent unnecessary overwrite */
- X return 0;
- X /* open mbox if: "autodelete" AND "hold" are NOT set. */
- X if (is_spool(mailfile)
- X && !(delete_it = !!do_set(set_options, "autodelete"))
- X && !(hold = !!do_set(set_options, "hold"))) {
- X register char *p;
- X int x = 1; /* tell getpath to ignore "ENOENT" if file not found */
- X
- X if (!(p = do_set(set_options, "mbox")))
- X p = DEF_MBOX;
- X mbox_file = getpath(p, &x);
- X if (x) {
- X if (x > 0)
- X print("%s is a directory.\n", mbox_file);
- X else
- X print("can't open %s: %s\n", p, mbox_file);
- X mbox = NULL_FILE;
- X } else {
- X char *mode = "a";
- X if (access(mbox_file, 0)) /* does it exist? */
- X mode = "w"; /* no, create it. */
- X else if (access(mbox_file, 2)) /* if yes, can we write in it? */
- X error("can't open %s", mbox_file); /* if no, print why not */
- X if (!(mbox = fopen(mbox_file, mode)))
- X error("can't open %s", mbox_file);
- X }
- X }
- X /* reopen the mailfile; make sure it's not readable */
- X {
- X int omask = umask(077);
- X mail_fp = fopen(mailfile, "w");
- X (void) umask(omask);
- X if (!mail_fp) {
- X error("can't rewrite %s", mailfile);
- X return 0;
- X }
- X }
- X turnon(glob_flags, IGN_SIGS);
- X print("Updating \"%s\"", mailfile), fflush(stdout);
- X#ifdef SYSV
- X (void) locking(fileno(mail_fp), LK_LOCK, 0);
- X#else
- X#ifdef BSD
- X if (flock(fileno(mail_fp), LOCK_EX))
- X error("WARNING: could not lock %s", mailfile);
- X#endif BSD
- X#endif SYSV
- X turnon(flg, UPDATE_STATUS);
- X turnon(flg, NO_IGNORE);
- X
- X for (i = 0; i < msg_cnt; i++)
- X /* check to see if message is marked for deletion or, if read and not
- X * preserved, delete it if autodelete is set. Otherwise, save the
- X * message in the spool file if hold is set. If all fails, save in mbox.
- X */
- X if (ison(msg[i].m_flags, DELETE)
- X || isoff(msg[i].m_flags, UNREAD) && isoff(msg[i].m_flags, PRESERVE)
- X && delete_it) {
- X Debug("%s %d",
- X (action!='d')? "\ndeleting message:" : "", i+1), action = 'd';
- X continue;
- X } else if (ison(msg[i].m_flags, UNREAD) ||
- X ison(msg[i].m_flags, PRESERVE) || hold || !mbox) {
- X j++;
- X Debug("%s %d",
- X (action!='s')? "\nsaving in spool:" : "", i+1), action = 's';
- X if (copy_msg(i, mail_fp, flg) == -1) {
- X error("WARNING: could not write back to spool");
- X print("ALL mail left in %s\n", tempfile);
- X print("Spool mailbox may be corrupted.\n");
- X if (new)
- X print("New mail may be lost. :-(\n");
- X dont_unlink = TRUE;
- X break;
- X }
- X } else if (is_spool(mailfile)) { /* copy back to mbox if spooldir */
- X k++;
- X if (copy_msg(i, mbox, flg) == -1) {
- X error("WARNING: could not write to mbox");
- X print("Unresolved mail left in %s\n", tempfile);
- X dont_unlink = TRUE;
- X break;
- X }
- X Debug("%s %d",
- X (action!='m')? "\nsaving in mbox:" : "", i+1), action = 'm';
- X }
- X Debug("\n%s", mailfile);
- X#ifdef SYSV
- X locking(fileno(mail_fp), LK_UNLCK, 0);
- X#endif SYSV
- X fclose(mail_fp); /* implicit unlock for BSD */
- X if (mbox)
- X fclose(mbox);
- X if (j) {
- X long times[2];
- X times[1] = time(×[0]) - (long)2;
- X if (is_spool(mailfile) && utime(mailfile, times))
- X error("utime");
- X print_more(": saved %d message%s\n", j, (j==1)? NO_STRING: "s");
- X } else if (!is_spool(mailfile) && !dont_unlink && !new)
- X if (unlink(mailfile))
- X turnon(glob_flags, CONT_PRNT), error(": cannot remove");
- X else
- X print_more(": removed\n");
- X else
- X print_more(": empty\n");
- X if (k)
- X print("saved %d message%s in %s\n",k,(k==1)? NO_STRING: "s",mbox_file);
- X if (new && !istool)
- X print("New mail has arrived.\n");
- X turnoff(glob_flags, IGN_SIGS);
- X#ifdef SUNTOOL
- X if (istool) {
- X mail_timer.it_value.tv_sec = time_out;
- X setitimer(ITIMER_REAL, &mail_timer, NULL);
- X }
- X#endif SUNTOOL
- X return 1;
- X}
- X
- Xmail_size()
- X{
- X struct stat buf;
- X if (!is_spool(mailfile)) {
- X char tmp[128];
- X if (!stat(sprintf(tmp, "%s/%s", MAILDIR, login), &buf))
- X spool_size = buf.st_size;
- X }
- X if (!*mailfile)
- X return 0;
- X if (stat(mailfile, &buf)) {
- X if (errno != ENOENT)
- X error("Can't stat %s", mailfile);
- X return 0;
- X }
- X if (is_spool(mailfile))
- X spool_size = buf.st_size;
- X if (buf.st_size > last_size) {
- X last_size = buf.st_size;
- X return 1;
- X }
- X return 0;
- X}
- X
- Xvoid
- Xmail_status(as_prompt)
- X{
- X static char buf[256];
- X register int cnt = 0, new = 0, unread = 0, deleted = 0;
- X
- X for ( ; cnt < msg_cnt; cnt++) {
- X if (ison(msg[cnt].m_flags, UNREAD))
- X unread++;
- X if (ison(msg[cnt].m_flags, DELETE))
- X deleted++;
- X if (isoff(msg[cnt].m_flags, OLD))
- X new++;
- X }
- X if (as_prompt) {
- X register char *p, *b = buf;
- X for (p = prompt; *p; p++)
- X if (*p == '\\')
- X switch (*++p) {
- X case 'n': case 'r': *b++ = '\n';
- X when 't': *b++ = '\t';
- X otherwise: *b++ = *p;
- X }
- X else if (*p == '%')
- X switch (*++p) {
- X case 'm':
- X b += strlen(sprintf(b,"%d",(msg_cnt)? current_msg+1:0));
- X when 't':
- X b += strlen(sprintf(b, "%d", msg_cnt));
- X when 'd':
- X b += strlen(sprintf(b, "%d", deleted));
- X when 'u':
- X b += strlen(sprintf(b, "%d", unread));
- X when 'n':
- X b += strlen(sprintf(b, "%d", new));
- X when 'f':
- X b += Strcpy(b, mailfile);
- X if (ison(glob_flags, READ_ONLY))
- X b += Strcpy(b, " [read only]");
- X when 'T': case 'D': case 'Y': case 'M': case 'N':
- X b += Strcpy(b, Time(p, (long)0));
- X otherwise: *b++ = *p;
- X }
- X else if (*p == '!')
- X b += strlen(sprintf(b, "%d", hist_no+1));
- X else
- X *b++ = *p;
- X *b = 0;
- X print("%s", buf); /* buf MIGHT have a % in it... don't pass as fmt */
- X return;
- X }
- X (void) sprintf(buf,"\"%s\"%s: %d message%s, %d new, %d unread",
- X mailfile, ison(glob_flags, READ_ONLY)? " [read only]" : "",
- X msg_cnt, (msg_cnt != 1)? "s": NO_STRING, new, unread);
- X if (istool || iscurses)
- X (void) sprintf(buf+strlen(buf), ", %d deleted", deleted);
- X#ifdef SUNTOOL
- X if (istool) {
- X static char ic_text[4];
- X extern struct pixrect mail_icon_image1, mail_icon_image2;
- X (void) sprintf(ic_text, "%3d", msg_cnt);
- X tool_set_attributes(tool,
- X WIN_LABEL, buf,
- X WIN_ICON_LABEL, ic_text,
- X WIN_ICON_IMAGE, ison(glob_flags, NEW_MAIL)?
- X &mail_icon_image2 : &mail_icon_image1,
- X 0);
- X } else
- X#endif SUNTOOL
- X#ifdef CURSES
- X if (iscurses)
- X mvprintw(0, 0, "%-3d %-*s",
- X ((msg_cnt)? current_msg+1 : 0), COLS-5, buf), clrtoeol();
- X else
- X#endif CURSES
- X puts(buf);
- X return;
- X}
- X
- X/* return -1 since function doesn't affect messages */
- Xcheck_flags(flags)
- Xu_long flags;
- X{
- X print_more(" ");
- X if (ison(flags, VERBOSE))
- X print_more("VERBOSE ");
- X if (ison(flags, INCLUDE))
- X print_more("INCLUDE ");
- X if (ison(flags, INCLUDE_H))
- X print_more("INCLUDE_H ");
- X if (ison(flags, EDIT))
- X print_more("EDIT ");
- X if (ison(flags, SIGN))
- X print_more("SIGN ");
- X if (ison(flags, DO_FORTUNE))
- X print_more("DO_FORTUNE ");
- X if (ison(flags, NO_HEADER))
- X print_more("NO_HEADER ");
- X if (ison(flags, DELETE))
- X print_more("DELETE ");
- X if (ison(flags, OLD))
- X print_more("OLD ");
- X if (ison(flags, UNREAD))
- X print_more("UNREAD ");
- X if (ison(flags, UPDATE_STATUS))
- X print_more("UPDATE_STATUS ");
- X if (ison(flags, NO_PAGE))
- X print_more("NO_PAGE ");
- X if (ison(flags, INDENT))
- X print_more("INDENT ");
- X if (ison(flags, NO_IGNORE))
- X print_more("NO_IGNORE ");
- X if (ison(flags, PRESERVE))
- X print_more("PRESERVE ");
- X print_more("\n");
- X return -1;
- X}
- END_OF_FILE
- if test 16268 -ne `wc -c <'msgs.c'`; then
- echo shar: \"'msgs.c'\" unpacked with wrong size!
- fi
- # end of 'msgs.c'
- fi
- if test -f 'mush.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush.h'\"
- else
- echo shar: Extracting \"'mush.h'\" \(17878 characters\)
- sed "s/^X//" >'mush.h' <<'END_OF_FILE'
- X/* @(#)mush.h (c) copyright 1986 (Dan Heller) */
- X
- X#define VERSION "Mail User's Shell (Vers 5.7) Sun Sep 6 19:10:48 PDT 1987"
- X
- X#include "config.h"
- X
- X#ifdef CURSES
- X#include <curses.h>
- X#else CURSES
- X#include <stdio.h>
- X#endif /* CURSES */
- X
- X#include <ctype.h>
- X#include <errno.h>
- X#include <setjmp.h>
- X#include "strings.h"
- X
- X#ifdef SUNTOOL
- X# include <suntool/tool_hs.h>
- X#else SUNTOOL
- X# include <sys/types.h>
- X# include <signal.h>
- X# ifndef SYSV
- X# include <sys/time.h>
- X# include <sys/ioctl.h> /* for ltchars */
- X# else
- X# include <time.h>
- X# include <fcntl.h>
- X# endif /* SYSV */
- X#endif /* SUNTOOL */
- X
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X
- X#ifdef SUNTOOL
- X# include <suntool/gfxsw.h>
- X# include <suntool/panel.h>
- X# include <suntool/ttysw.h>
- X# include <suntool/ttytlsw.h>
- X# include <suntool/menu.h>
- X# include <suntool/icon_load.h>
- X#endif /* SUNTOOL */
- X
- X/* if no maximum number of files can be found, we'll use getdtablesize() */
- X#ifdef _NFILE
- X# define MAXFILES _NFILE
- X#else
- X#ifdef NOFILE
- X# define MAXFILES NOFILE
- X#endif
- X#endif
- X
- X#ifndef CTRL
- X#define CTRL(c) ('c' & 037)
- X#endif
- X
- X#define ESC '\033'
- X
- X#define NO_STRING ""
- X#ifdef NULL
- X#undef NULL
- X#endif /* NULL */
- X#define NULL (char *)0
- X#define NULL_FILE (FILE *)0
- X#define DUBL_NULL (char **)0
- X#define TRPL_NULL (char ***)0
- X#ifdef putchar
- X#undef putchar
- X#endif /* putchar */
- X#define putchar(c) fputc(c, stdout)
- X#define bell() fputc('\007', stderr)
- X
- X#define on_intr() \
- X turnoff(glob_flags, WAS_INTR), oldint = signal(SIGINT, interrupt), \
- X oldquit = signal(SIGQUIT, interrupt)
- X
- X#define off_intr() \
- X turnoff(glob_flags, WAS_INTR), (void) signal(SIGINT, oldint), \
- X (void) signal(SIGQUIT, oldquit)
- X
- X/* Don't flush input when setting echo or cbreak modes (allow typeahead) */
- X#ifdef TIOCSETN
- X#define stty(fd, sgttybuf) (ioctl(fd, TIOCSETN, sgttybuf))
- X#endif /* TIOCSETN */
- X
- X#ifndef CURSES
- X/* if curses is not defined, simulate the same tty based macros */
- Xstruct sgttyb _tty;
- X
- X#define crmode() (_tty.sg_flags |= CBREAK, stty(0, &_tty))
- X#define nocrmode() (_tty.sg_flags &= ~CBREAK, stty(0, &_tty))
- X#define echo() (_tty.sg_flags |= ECHO, stty(0, &_tty))
- X#define noecho() (_tty.sg_flags &= ~ECHO, stty(0, &_tty))
- X#define savetty() (void) gtty(0, &_tty)
- X#endif /* ~CURSES */
- X
- X#define echo_on() \
- X if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) echo(), nocrmode()
- X#define echo_off() \
- X if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) noecho(), crmode()
- X
- X#define strdup(dst, src) (xfree (dst), dst = savestr(src))
- X#define Debug if (debug) printf
- X
- X#ifdef SYSV
- X#define L_SET 0
- X#define F_OK 000
- X#define R_OK 004
- X#define W_OK 002
- X#define E_OK 001
- X#define u_long ulong_t
- X#define vfork fork
- X#define SIGCHLD SIGCLD
- X#endif /* SYSV */
- X
- X#if !defined(SUNTOOL) && !defined(CURSES)
- X
- X#define TRUE 1
- X#define FALSE 0
- X#define print printf
- X#define wprint printf
- X#define print_more printf
- X
- X#endif /* SUNTOOL && !CURSES */
- X
- X#ifndef max
- X#define max(a,b) (((a) > (b)) ? (a) : (b))
- X#define min(a,b) (((a) < (b)) ? (a) : (b))
- X#endif /* max */
- X
- X#if defined(CURSES) && !defined(SUNTOOL)
- X#define wprint printf
- X#endif /* !SUNTOOL && CURSES */
- X
- X#if defined(CURSES) || defined(SUNTOOL)
- X#define print_more turnon(glob_flags, CONT_PRNT), print
- Xvoid print(); /* printf to window or curses or tty accordingly */
- X#endif /* CURSES || SUNTOOL */
- X
- X#ifdef SUNTOOL
- X
- X#define NO_ITEM (Panel_item)0
- X#define NO_EVENT (struct inputevent *)0
- X#define TIME_OUT 60 /* sleep 60 secs between mailchecks */
- X#define PIX_OR PIX_SRC ^ PIX_DST
- X#define ID event.ie_code
- X#define l_width(font) fonts[font]->pf_defaultsize.x /* width of letter */
- X#define l_height(font) fonts[font]->pf_defaultsize.y /* height of letter */
- X#define Clrtoeol(w,x,y,f) pw_text(w, x, y, PIX_SRC, fonts[f], blank)
- X
- X#define highlight(win,x,y,font,s) \
- X pw_text(win,x,y, PIX_SRC, fonts[font],s), \
- X pw_text(win,x+1,y, \
- X (ison(glob_flags, REV_VIDEO))? PIX_NOT(PIX_SRC): PIX_SRC|PIX_DST, \
- X fonts[font],s)
- X
- X/* Fonts */
- X#define FONTDIR "/usr/lib/fonts/fixedwidthfonts"
- X#define DEFAULT 0
- X#define SMALL 1
- X#define LARGE 2
- X#define MAX_FONTS 3
- X
- X#endif /* SUNTOOL */
- X
- X/* bits and pieces */
- X#define turnon(flg,val) ((flg) |= ((u_long)1 << ((u_long)(val)-1L)))
- X#define turnoff(flg,val) ((flg) &= ~((u_long)1 << ((u_long)(val)-1L)))
- X#define ison(flg,val) ((u_long)(flg) & ((u_long)1 << ((u_long)(val)-1L)))
- X#define isoff(flg,val) (!ison((flg), (val)))
- X#define set_isread(n) \
- X if (ison(msg[n].m_flags, UNREAD)) \
- X turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD)
- X
- X/* msg lists represented by bits */
- X#define clear_msg_list(list) (void) bzero(list, (msg_cnt+7)/8)
- X#define msg_bit(list, n) ((list[(n) / 8] >> ((n) % 8)) & 1)
- X#define set_msg_bit(list, n) (list[(n) / 8] |= (1 << ((n) % 8)))
- X#define unset_msg_bit(list, n) (list[(n) / 8] &= ~(1 << ((n) % 8)))
- X#define bput(S1, S2, Len, op) \
- X { \
- X register char *s1 = S1, *s2 = S2; \
- X register int len = Len; \
- X while(len--) \
- X *s2++ op *s1++; \
- X }
- X#define bitput(m1,m2,len,op) bput(m1, m2, (((len)+7)/8), op)
- X
- X/* convenience and/or readability */
- X#define when break;case
- X#define otherwise break;default
- X#define lower(c) (isupper(c)? tolower(c): c)
- X#define Lower(c) (c = lower(c))
- X#define upper(c) (islower(c)? toupper(c): c)
- X#define Upper(c) (c = upper(c))
- X#define skipspaces(n) for(p += (n); *p == ' ' || *p == '\t'; ++p)
- X#define skipdigits(n) for(p += (n); isdigit(*p); ++p)
- X
- X#define NO_FLG 0
- X
- X/* various flags */
- Xlong glob_flags; /* global boolean flags thruout the whole program */
- X#define DO_UPDATE 1 /* check for changes to avoid unnecessary copyback */
- X#define REV_VIDEO 2 /* reverse video for curses or toolmode */
- X#define CONT_PRNT 3 /* continue to print (maybe a printf) without a '\n' */
- X#define DO_SHELL 4 /* run a shell even if no mail? (true if tool) */
- X#define DO_PIPE 5 /* true if commands are piping to another command */
- X#define IS_PIPE 6 /* true if commands' "input" is piped from another */
- X#define IGN_SIGS 7 /* true if catch() should not longjump */
- X#define IGN_BANG 8 /* ignore ! as a history reference (see source()) */
- X#define ECHO_FLAG 9 /* if true, echo|cbreak is ON, don't echo typing (-e) */
- X#define IS_GETTING 10 /* true if we're getting input for a letter */
- X#define PRE_CURSES 11 /* true if curses will be run, but hasn't started yet */
- X#define READ_ONLY 12 /* -r passed to folder() (or main) setting read only */
- X#define REDIRECT 13 /* true if stdin is being redirected */
- X#define WAS_INTR 14 /* catch interrupts, set this flag (signals.c) */
- X#define WARNING 15 /* if set, various warning messages may be printed */
- X#define NEW_MAIL 17 /* new mail has arrived; user is busy or in icon mode */
- X
- X#define VERBOSE 1 /* verbose flag for sendmail */
- X#define INCLUDE 2 /* include msg in response */
- X#define INCLUDE_H 3 /* include msg with header */
- X#define EDIT 4 /* enter editor by defualt on mailing */
- X#define SIGN 5 /* auto-include ~/.signature in mail */
- X#define DO_FORTUNE 6 /* add a fortune at end of msgs */
- X
- X/* msg flags */
- X#define NO_HEADER 7 /* don't print header of message (top, write) */
- X#define DELETE 8
- X#define OLD 9
- X#define UNREAD 10
- X#define UPDATE_STATUS 11 /* change status of msg when copyback */
- X#define NO_PAGE 12 /* don't page this message */
- X#define INDENT 13 /* indent included msg with string */
- X#define NO_IGNORE 14 /* don't ignore headers */
- X#define PRESERVE 15 /* preserve in mailbox unless deleted */
- X#define TOP 15 /* just print the top of the message */
- X#define FORWARD 16 /* Forward messages into the message buffer */
- X
- X#define MAXMSGS_BITS MAXMSGS/sizeof(char) /* number of bits for bitmap */
- X
- Xstruct msg {
- X u_long m_flags;
- X long m_offset; /* offset in tempfile of msg */
- X long m_size; /* number of bytes in msg */
- X int m_lines; /* number of lines in msg */
- X} msg[MAXMSGS];
- X
- Xstruct options {
- X char *option;
- X char *value;
- X struct options *next;
- X} *set_options, *aliases, *ignore_hdr, *functions, *fkeys, *own_hdrs;
- X#ifdef CURSES
- Xstruct options *bindings;
- X#endif /* CURSES */
- X
- Xstruct cmd {
- X char *command;
- X int (*func)();
- X};
- Xextern struct cmd ucb_cmds[];
- Xextern struct cmd cmds[], hidden_cmds[];
- X#ifdef SUNTOOL
- Xextern struct cmd fkey_cmds[];
- X#endif /* SUNTOOL */
- X
- XFILE
- X *tmpf, /* temporary holding place for all mail */
- X *open_file(), /* open a file or program for write/append */
- X *popen(); /* this should be in stdio.h */
- X
- Xextern char
- X *sys_errlist[], /* system's list of global error messages */
- X#ifdef SUNTOOL
- X *font_files[], /* the names of the files fonts are kept in */
- X *alt_fonts[], /* fonts to use if first ones don't work */
- X#endif /* SUNTOOL */
- X **environ; /* user's environment variables */
- X
- Xextern int errno; /* global system error number */
- Xjmp_buf jmpbuf; /* longjmp to jmpbuf on sigs (not in tool) */
- X
- Xchar
- X debug, /* debug causes various print statements in code */
- X tempfile[40], /* path to filename of temporary file */
- X msg_list[MAXMSGS_BITS], /* MAXMSGS bits of boolean storage */
- X *cmd_help, /* filename of location for "command -?" commands. */
- X *login, /* login name of user */
- X *mailfile, /* path to filename of current mailfile */
- X *ourname[MAX_HOST_NAMES], /* the name and aliases of the current host */
- X *prompt, /* the prompt string -- may have %d */
- X *escape, /* the escape character when without editor */
- X *editor, /* string describing editor to use (default vi) */
- X *hdrs_only, /* true if -H flag was given --set to args */
- X *hdr_format, /* set to the header format string; referenced a lot */
- X *visual, /* string describing visual editor to use */
- X *pager, /* string describing pager to use (default more) */
- X *argv_to_string(), /* convert a vector of strings into one string */
- X **make_command(), /* build a command vector (argv) */
- X **mk_argv(), /* given a string, make a vector */
- X *itoa(), /* return a string representation of a number */
- X *lcase_strcpy(), /* just like strcpy, but convert all chars to lower */
- X *variable_stuff(), /* return information about variables */
- X *no_newln(), /* remove newline and extra whitespace - return end */
- X *savestr(), /* strcpy arg into malloc-ed memory; return address */
- X *date_to_string(), /* returns a string described by parse_date() */
- X *msg_date(), /* return a string of the date of a message */
- X *parse_date(), /* parse an ascii date, and return message-id str */
- X *Time(), /* returns string expression of time (takes args) */
- X *do_range(), /* parse a string converting to a "range" of numbers */
- X *getpath(), /* static char returning path (expanding ~, +, %, #) */
- X *compose_hdr(), /* returns a formatted line describing passed msg # */
- X *my_atoi(), /* do an atoi, but return the last char parsed */
- X *do_set(), /* set/unset an option, alias, ignored-hdr */
- X *reply_to(), /* who do we reply to when responding */
- X *cc_to(), /* when responding, return str which is the cc-list */
- X *subject_to(), /* when responding, return str which is the subject */
- X *header_field(), /* the line in msg described by arg (message header) */
- X *alias_to_address(),/* convert a name[list] to "real" names */
- X *set_header(), /* [interactive] proc to set/display to/subject/cc */
- X *getenv(), *prog_name;
- X
- Xint
- X last_msg_cnt, /* when checking for new mail, save the last msg_cnt */
- X msg_cnt, /* total number of messages */
- X crt, /* min number of lines msg contains to invoke pager */
- X current_msg, /* the current message we're dealing with */
- X exec_pid, /* pid of a command that has been "exec"ed */
- X hist_no, /* command's history number */
- X iscurses; /* if we're running curses */
- X istool, /* argv[0] == "xxxxtool", ranges from 0 to 2 */
- X n_array[128], /* array of message numbers in the header window */
- X screen, /* number of headers window can handle */
- X
- X quit(), cleanup(), catch(), do_alias(), respond(), cd(), sh(), stop(),
- X folder(), save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(),
- X rm_edfile(), pick(), save_opts(), preserve(), sort(), readmsg(),
- X do_pick(), print_help(), folders(), question_mark(), do_from(), my_stty(),
- X do_version(), disp_hist(), source(), do_echo(), sigchldcatcher(), ls(),
- X nopenfiles(), Setenv(), Unsetenv(), Printenv(), bus_n_seg(), msg_flags(),
- X toggle_debug(), stop_start(), interrupt();
- X
- Xlong
- X still_more, /* there is still more message to display */
- X spool_size, /* size of sppol mail regardless of current folder */
- X last_size, /* the lastsize of the mailfile since last check */
- X time(); /* satisfy lint */
- X
- Xvoid
- X xfree(), free_vec(), error(), getmail(), mail_status(),
- X file_to_fp(), init(), display_msg(), c_more();
- X /* printf(), fclose(), fflush(), fputs(), fputc() */
- X#ifndef CURSES
- Xstruct sgttyb _tty; /* tty characteristics */
- X#endif /* CURSES */
- X#ifdef TIOCGLTC
- Xstruct ltchars ltchars; /* tty character settings */
- X#endif /* TIOCGLTC */
- X
- X#ifdef CURSES
- X
- X#define STANDOUT(y,x,s) standout(), mvaddstr(y,x,s), standend()
- X#define redraw() clearok(curscr, TRUE), wrefresh(curscr)
- X
- Xint
- X curses_init(), /* interpret commands via the curses interface */
- X bind_it(); /* bind chars or strings to functions */
- X#endif /* CURSES */
- X
- X#ifdef SUNTOOL
- Xvoid
- X lock_cursors(), unlock_cursors(), scroll_win(),
- X set_fkeys(), set_key(), toggle_opt(), help_opt();
- X
- Xchar
- X *rite(), /* rite a char to msg_win: return string if c == '\n' */
- X *find_key(), /* pass x,y coords to find which function key assoc. */
- X *key_set_to(), /* pass fkey string, return string describing func */
- X *panel_get(), /* returns what has been typed in a panel item */
- X *tool_help, /* help for tool-related things (sometimes, overlap) */
- X blank[128]; /* use to clear to end of line */
- X
- Xint
- X time_out, /* time out interval to wait for new mail */
- X rootfd, /* the root window's fd */
- X parentfd, /* the parent's window fd */
- X getting_opts, /* true if getting/setting opts from msg_win */
- X curfont, /* the current font to use for mail message window */
- X total_fonts, /* total number of fonts available */
- X get_hdr_field, /* bitmask of header fields to be gotten */
- X
- X msg_io(), msgwin_handlesigwinch(), hdr_io(), hdrwin_handlesigwinch(),
- X sigchldcatcher(), sigtermcatcher(), sigwinchcatcher(), do_sort(),
- X do_compose(), do_edit(), read_mail(), delete_mail(), respond_mail(),
- X do_hdr(), display_hdrs(), print_sigwinch(), p_set_opts(),
- X tool_mgmt(), do_help(), text_done(), msg_num_done(), do_lpr(),
- X toolquit(), change_font(), do_clear(), do_update(),
- X file_dir(), do_file_dir(), do_send(), abort_mail(), check_new_mail(),
- X fkey_cmd(), fkey_settings();
- X
- Xstruct tchars tchars; /* more tty character settings */
- X
- Xstruct tool *tool; /* main tool structure */
- Xstruct toolsw
- X *panel_sw, /* main panel subwindow */
- X *hdr_sw, /* subwindow for message headers */
- X *hdr_panel_sw, /* panel for headers */
- X *tty_sw, /* subwindow which forks a shell (usually editor) */
- X *print_sw, /* subwindow for print statements */
- X *msg_sw; /* main subwindow to display messages and more */
- X
- Xstruct pixwin
- X *msg_win, /* main pixwin for message display and more */
- X *hdr_win, /* pixwin for message headers */
- X *print_win; /* pixwin for printing messages ( print() ) */
- X
- Xstruct pr_pos txt; /* current position of text written */
- Xstruct rect msg_rect, hdr_rect; /* sizes of the main and hdr rects */
- Xstruct pixfont *fonts[MAX_FONTS]; /* array of fonts */
- X
- XPanel
- X main_panel, /* the main panel dealing with generic items */
- X hdr_panel; /* panel which contains message header specific items */
- X
- XPanel_item
- X abort_item, /* abort mail in progress */
- X alias_item, /* set/view/change current mail aliases */
- X cd_item, /* changes file_item to cd (for cd-ing) */
- X comp_item, /* compose a letter */
- X delete_item, /* delete/undelete messages */
- X edit_item, /* edit a message */
- X font_item, /* choose which font to use */
- X folder_item, /* change folders */
- X file_item, /* text item for files or directories (forlder/cd) */
- X hdr_display, /* format message headers are displayed */
- X help_item, /* choose this to get various help */
- X ignore_item, /* set/view/change message headers to be ignored */
- X input_item, /* text item to get values for set/unsetting values */
- X msg_num_item, /* text item to explicity state which message to read */
- X next_scr, /* display the next screenful of message headers */
- X option_item, /* set/view/unset mail options */
- X prev_scr, /* display the previous screen of messages */
- X print_item, /* send current message to the printer */
- X quit_item, /* quit tool/close to icon */
- X read_item, /* read the current message */
- X respond_item, /* respond to messages */
- X save_item, /* saves messages; uses text item input_item */
- X send_item, /* when composing letter, this will send it off */
- X sort_item, /* sort routine... */
- X sub_hdr_item[6], /* display items that just sit there and give help */
- X update_item; /* commit changes to folder */
- X
- Xstruct itimerval mail_timer; /* frequency to check for new mail */
- X
- X /* mouse symbols and data */
- X/* left, middle and right mouse pixrects */
- Xstruct cursor
- X l_cursor, m_cursor, r_cursor, coffee, read_cursor, write_cursor,
- X main_cursor, checkmark;
- X
- Xstruct pixrect *msg_pix; /* pixrect holding text of a message */
- Xextern struct pixrect mouse_left, mouse_middle, mouse_right;
- Xextern struct pixrect dn_arrow, up_arrow, cycle, shade_50;
- X
- Xextern struct icon mail_icon;
- X#endif /* SUNTOOL */
- END_OF_FILE
- if test 17878 -ne `wc -c <'mush.h'`; then
- echo shar: \"'mush.h'\" unpacked with wrong size!
- fi
- # end of 'mush.h'
- fi
- echo shar: End of archive 6 \(of 12\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-